/*
Copyright 2008, 2009 Joonas Lehtolahti

This file is part of Openfire-C.

Openfire-C is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Openfire-C is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with Openfire-C.  If not, see <http://www.gnu.org/licenses/>.
*/

/* This file contains some functions to help testing the library */

#include <stdio.h>
#include <string.h>
#include "XfirePacket.h"
#include "XfirePacketDebug.h"

/*
 * DumpPacket (struct XfirePacket *testpack, const char *indent)
 *   Writes packet data to stdout in human readable form, indented by indent
 * 
 * Parameters:
 *   testpack   pointer to struct XfirePacket
 *   indent     character array that prefixes all lines
 * 
 * Returns:
 *   nothing
 */
DLLEXPORT(void) DumpPacket(struct XfirePacket *testpack, const char * indent, const char *color1, const char *color2) {
	unsigned int attr_index;
	unsigned char *temp;
	
	printf("%s%sPacket id: %s%04x\n", indent, color1, color2, testpack->pid);
	printf("%s%sPacket length: %d\n", indent, color1, testpack->length);
	printf("%s%sAttributes: %d\n", indent, color1, testpack->attrs);
	printf("%s%sShort names: %d\n", indent, color1,testpack->shortnames);
	
	for (attr_index = 0; attr_index < testpack->attrs; attr_index++) {
		struct XfirePattr *attr = testpack->attributes[attr_index];
		
		printf("\n%s%sAttribute %d: ", indent, color1, attr_index+1);
		
		if (testpack->shortnames)
			printf("%s%02x\n", color2, *(attr->name->s));
		else {
			temp = non2char(attr->name);
			printf("%s%s\n", color2, temp);
			free(temp);
		}
		
		printf("%s%sData type: %s%02x\n", indent, color1, color2, attr->aid);
		
		DumpAttr(attr->attr, attr->aid, indent, color1, color2);
	}
	
}

/*
 * DumpAttr (void *attr, int aid, const char *indent)
 *   Writes attribute data to stdout in human readable form, indented by indent
 * 
 * Parameters:
 *   attr     pointer to attribute data
 *   aid      attribute type
 *   indent   character array that prefixes all lines
 * 
 * Returns:
 *   nothing
 */
void DumpAttr(void *attr, int aid, const char *indent, const char *color1, const char *color2) {
	unsigned int i;
	unsigned char *temp;
	char *newindent;
	size_t indentlevel;
	struct XfirePattr4 * lister;
	
	printf("%s%sValue: %s", indent, color1, color2);
	
	switch (aid) {
		case XFP_TYPE_INT:
			printf("%u (0x%08x)\n",*(unsigned int*)(attr),*(unsigned int*)(attr));
			break;
		
		case XFP_TYPE_BOOLEAN:
			printf("%u (0x%02x)\n",*(unsigned int*)(attr),*(unsigned int*)(attr));
			break;
			
		case XFP_TYPE_LONG:
			printf("%llu (0x%016llx)\n",*(unsigned long long int*)(attr),*(unsigned long long int*)(attr));
			break;
			
		case XFP_TYPE_STRING:
			temp = non2char((non0string*)attr);
			
			printf("%s\n",temp);
			printf("%s%sLength: %d\n",indent,color1,((non0string*)attr)->l);
			
			free(temp);
			break;
			
		case XFP_TYPE_SID:
			temp = ((non0string*)attr)->s;
			for (i=0;i<XFP_SIZE_ATTRSIDVALUE;i++)
				printf("%02x ",temp[i]);
			puts("");
			break;
			
		case XFP_TYPE_GCID:
			temp = ((non0string*)attr)->s;
			for (i=0;i<XFP_SIZE_ATTRGCIDVALUE;i++)
				printf("%02x ",temp[i]);
			puts("");
			break;
			
		case XFP_TYPE_LIST:
			indentlevel = strlen(indent)+4;
			newindent = (char*)malloc(sizeof(char)*(indentlevel+1));
			sprintf(newindent, "%*s", (int)indentlevel, " ");
			
			lister = (struct XfirePattr4 *)attr;
			printf("\n%s%sList of type %s%02x%s with %d items:\n", indent, color1, color2, lister->aid, color1, lister->size);
			for (i=0; i<lister->size; i++) {
				DumpAttr(lister->attr[i], lister->aid, newindent, color1, color2);
			}
			
			free(newindent);
			break;
			
		case XFP_TYPE_PACKET:
		case XFP_TYPE_NPACKET:
			printf("\n%s%sPacket type:\n", indent, color1);
			indentlevel = strlen(indent)+4;
			newindent = (char*)malloc(sizeof(char)*(indentlevel+1));
			sprintf(newindent, "%*s", (int)indentlevel, " ");
			
			DumpPacket((struct XfirePacket *)attr, newindent, color1, color2);
			
			free(newindent);
			break;
	}

}
